﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Seesmic.Sdp.Extensibility;
using Seesmic.Sdp.Utils;

using System.Threading;
using System.ComponentModel;
using System.Collections.Generic;

using PTiRouZ.Net.SilverLight.Api;
using PTiRouZ.Net.SilverLight.Api.HelloTipi;
using System.Collections.ObjectModel;

namespace Seesmic.HelloTipi
{
    public class HelloTipiSession : ISession, IDisposable
    {

        private HelloTipiAccount _account;
        private ISidebarAction _SidebarItem;

        public apitxt api;

        private ObservableCollection<KeyValuePair<string, FamilyPostingProvider>> _PostingProviders;
        private ObservableCollection<KeyValuePair<string, HelloTipiFamilyTimeLineItemsProvider>> _FamilyTimeLineItemsProviders;
        private ObservableCollection<KeyValuePair<string, HelloTipiSideBarAction>> _SideBarsAction;
        private ObservableCollection<KeyValuePair<string, HelloTipiFamilyPhotosSideBarAction>> _FamilyPhotosSideBarAction;

        HelloTipiFriendsTimeLineItemsProvider friends_ItemProvider;
        HelloTipiFamilyTimeLineItemsProvider family_ItemProvider;
        HelloTipiUserTimeLineItemsProvider Sent_ItemProvider;
        HelloTipiDirectMessagesTimeLineItemsProvider Private_ItemProvider;

        public int UserId
        {
            get;
            private set;
        }

        public /*override*/ string Id
        {
            get
            {
                return this._account.Id;
            }
        }

        public HelloTipiSession(HelloTipiAccount owner)
        {

            //HelloTipiPlugin.StorageService.DeleteValue(HelloTipiPlugin.PluginId, "SitesNameList");
            //HelloTipiPlugin.StorageService.DeleteValue(HelloTipiPlugin.PluginId, "SitesList");           
            HelloTipiPlugin.LogInfo("--------== HelloTipiSession ==---------");
            HelloTipiPlugin.LogInfo("Liste des noms de sites en cache: " + HelloTipiPlugin.SitesNameList.ToConcatenatedString<string>(x => x + ','));
            HelloTipiPlugin.LogInfo("Liste des sites en cache : " + HelloTipiPlugin.SitesList.ToConcatenatedString<my_sites>(x => x.name + ','));


            if (SynchronizationContext.Current == null)
            {
                throw new InvalidOperationException("A HelloTipi Session instance can only be created on the UI thread.");
            }

            this._account = owner;

            _PostingProviders = new ObservableCollection<KeyValuePair<string, FamilyPostingProvider>>();
            _FamilyTimeLineItemsProviders = new ObservableCollection<KeyValuePair<string, HelloTipiFamilyTimeLineItemsProvider>>();
            _SideBarsAction = new ObservableCollection<KeyValuePair<string, HelloTipiSideBarAction>>();
            _FamilyPhotosSideBarAction = new ObservableCollection<KeyValuePair<string, HelloTipiFamilyPhotosSideBarAction>>();

            this.api = new apitxt(this._account.Username, this._account.Password, "Seesmic Desktop 2");
            //this.api.VerifyCredentialsCompleted += new VerifyCredentialsEventHandler(api_VerifyCredentialsCompleted);

            this.api.APICallError += delegate(object sender, ApiErrorEventArgs e)
            {
                HelloTipiPlugin.ShowDialogNotification("Erreur de l'api", "{0}", DialogNotificationButtons.OK, e.Message);
            };

            this.api.MySitesCompleted += delegate(object sender, MySitesEventArgs e)
            {

                HelloTipiPlugin.LogInfo("--------== MySitesCompleted ==---------");

                ObservableCollection<string> _sitesNameList = new ObservableCollection<string>();

                _sitesNameList.Clear();
                e.result.ForEach(delegate(my_sites site)
                {
                    _sitesNameList.Add(site.name);
                });
                
                //Premier démmarage
                if (HelloTipiPlugin.SitesList.Count == 0)
                {
                    HelloTipiPlugin.LogInfo("Premier démarrage");
                    RegisterFamilyItems(e.result);                                                                  
                }
                else
                {
                    //On supprime les postingProvider obsolète déja enregistrer via le cache                                                                            
                    _PostingProviders.ForEach(delegate(KeyValuePair<string, FamilyPostingProvider> provider)
                    {
                        if (_sitesNameList.IndexOf(provider.Key) < 0)
                        {
                            HelloTipiPlugin.PostingService.UnregisterPostingProvider(provider.Value);
                            HelloTipiPlugin.LogInfo(String.Format("{0} à été supprimé de vos sites de famille", provider.Key));
                            HelloTipiPlugin.ShowBarNotification("HelloTipi", "{0} à été supprimé de vos sites de famille", provider.Key, BarNotificationKind.Info);
                        }
                    });

                    //On supprime les timeline obsolète déja enregistrer via le cache                                
                    _FamilyTimeLineItemsProviders.ForEach(delegate(KeyValuePair<string, HelloTipiFamilyTimeLineItemsProvider> timeline)
                    {
                        if (_sitesNameList.IndexOf(timeline.Key) < 0)
                        {
                            HelloTipiPlugin.SessionService.UnregisterTimelineItemsProvider(timeline.Value);
                            HelloTipiPlugin.LogInfo(String.Format("la timeline du site {0} à été supprimé ", timeline.Key));
                        }
                    });

                    //On supprime les sidebars obsolète déja enregistrer via le cache                                
                    _SideBarsAction.ForEach(delegate(KeyValuePair<string, HelloTipiSideBarAction> sidebar)
                    {
                        if (_sitesNameList.IndexOf(sidebar.Key) < 0)
                        {
                            (this._SidebarItem as HelloTipiSideBarAction).SidebarActions.Remove(sidebar.Value);
                            HelloTipiPlugin.LogInfo(String.Format("la sidebar du site {0} à été supprimé ", sidebar.Key));
                        }
                    });

                    //On ajoute les nouveaux sites de famille s'il y a besoin
                    e.result.ForEach(delegate(my_sites site)
                    {
                        //Ajout : On regarde dans la liste des nom de site s'il y et deja
                        if (HelloTipiPlugin.SitesNameList.IndexOf(site.name) < 0)
                        {
                            HelloTipiPlugin.LogInfo("On as pas trouve le site " + site.name + " dans la liste !!!");
                            //on ajoute le site de famille
                            FamilyPostingProvider fpp = new FamilyPostingProvider(this, site.name);
                            _PostingProviders.Add(new KeyValuePair<string, FamilyPostingProvider>(site.name, fpp));
                            HelloTipiPlugin.PostingService.RegisterPostingProvider(fpp);
                            addSiteTimeLine(site);

                            HelloTipiPlugin.LogInfo(String.Format("{0} à été ajouté à vos sites de famille", site.name));
                            HelloTipiPlugin.ShowBarNotification("HelloTipi", "{0} à été ajouté à vos sites de famille", site.name, BarNotificationKind.Info);
                        }

                    });
                }
                HelloTipiPlugin.SitesList = e.result;
                HelloTipiPlugin.SitesNameList = _sitesNameList;

                HelloTipiPlugin.LogInfo("Liste des noms de sites ajoutées : " + HelloTipiPlugin.SitesNameList.ToConcatenatedString<string>(x => x + ','));
                HelloTipiPlugin.LogInfo("Liste des sites ajoutées : " + HelloTipiPlugin.SitesList.ToConcatenatedString<my_sites>(x => x.name + ','));

            };

            InitializeExtraSideBar();

            InitializeSidebarItem();


        }  
      

        void api_VerifyCredentialsCompleted(object sender, VerifyCredentialsEventArgs e)
        {
            //HelloTipiPlugin.LogInfo("Création de la timeline");

            //HelloTipiPlugin.LogInfo("On appelle les sites");            
        }

        private void RegisterFamilyItems(ObservableCollection<my_sites> FamillySiteList)
        {
            FamillySiteList.ForEach(delegate(my_sites site)
            {
                //HelloTipiPlugin.SitesNameList.Add(site.name);
                _PostingProviders.Add(new KeyValuePair<string, FamilyPostingProvider>(site.name, new FamilyPostingProvider(this, site.name)));
                addSiteTimeLine(site);
                HelloTipiPlugin.LogInfo(String.Format("Timeline {0} ajouté", site.name));

                _FamilyPhotosSideBarAction.Add(new KeyValuePair<string, HelloTipiFamilyPhotosSideBarAction>(site.name, new HelloTipiFamilyPhotosSideBarAction(_account, site.name)));
                HelloTipiPlugin.LogInfo(String.Format("SideBarPhotos {0} ajouté", site.name));
                //HelloTipiPlugin.ShowBarNotification("HelloTipi", "{0} à été ajouté à vos sites de famille", site.name, BarNotificationKind.Info);
            });

            _PostingProviders.ForEach<KeyValuePair<string, FamilyPostingProvider>>(delegate(KeyValuePair<string, FamilyPostingProvider> provider)
            {
                HelloTipiPlugin.PostingService.RegisterPostingProvider(provider.Value);
            });

            _FamilyPhotosSideBarAction.ForEach<KeyValuePair<string, HelloTipiFamilyPhotosSideBarAction>>(delegate(KeyValuePair<string, HelloTipiFamilyPhotosSideBarAction> FamilyPhotosSideBarAction)
            {
                HelloTipiPlugin.ShellService.RegisterSidebarAction(SidebarActionCategory.Extras, FamilyPhotosSideBarAction.Value);
            });
       }

        private void addSiteTimeLine(my_sites site)
        {
            family_ItemProvider = new HelloTipiFamilyTimeLineItemsProvider(this._account, site.name);
            HelloTipiPlugin.SessionService.RegisterTimelineItemsProvider(family_ItemProvider);

            _FamilyTimeLineItemsProviders.Add(new KeyValuePair<string, HelloTipiFamilyTimeLineItemsProvider>(site.name, family_ItemProvider));

            HelloTipiSideBarAction sidebarItem = new HelloTipiSideBarAction(this._account, family_ItemProvider);
            sidebarItem.Text = site.name;
            sidebarItem.Title = site.title; //string.Format("{0} / {1}", this.Account.Username, site.name);
            (this._SidebarItem as HelloTipiSideBarAction).AddTimelineSidebarItem(sidebarItem);

            _SideBarsAction.Add(new KeyValuePair<string, HelloTipiSideBarAction>(site.name, sidebarItem));
        }



        private void InitializeSidebarItem()
        {
            //HelloTipiPlugin.LogInfo("InitializeSidebarItem");
            friends_ItemProvider = new HelloTipiFriendsTimeLineItemsProvider(this._account);

            HelloTipiPlugin.SessionService.RegisterTimelineItemsProvider(friends_ItemProvider);

            HelloTipiSideBarAction action = new HelloTipiSideBarAction(this._account, friends_ItemProvider);
            action.Text = this.Account.Username;
            this._SidebarItem = action;

            //Sent
            Sent_ItemProvider = new HelloTipiUserTimeLineItemsProvider(this._account);
            HelloTipiPlugin.SessionService.RegisterTimelineItemsProvider(Sent_ItemProvider);

            HelloTipiSideBarAction sidebarSentItem = new HelloTipiSideBarAction(this._account, Sent_ItemProvider);
            sidebarSentItem.Text = "Messages envoyés";
            sidebarSentItem.Title = "Messages envoyés";
            (this._SidebarItem as HelloTipiSideBarAction).AddTimelineSidebarItem(sidebarSentItem);

            //Private
            Private_ItemProvider = new HelloTipiDirectMessagesTimeLineItemsProvider(this._account);
            HelloTipiPlugin.SessionService.RegisterTimelineItemsProvider(Private_ItemProvider);

            HelloTipiSideBarAction sidebarPrivateItem = new HelloTipiSideBarAction(this._account, Private_ItemProvider);
            sidebarPrivateItem.Text = "Messages privées";
            sidebarPrivateItem.Title = "Messages privées";
            (this._SidebarItem as HelloTipiSideBarAction).AddTimelineSidebarItem(sidebarPrivateItem);

            if(HelloTipiPlugin.SitesList.Count > 0) {
                RegisterFamilyItems(HelloTipiPlugin.SitesList);
            }           
        }

        private void InitializeExtraSideBar()
        {
            HelloTipiFavoritesPhotosSideBarAction fav = new HelloTipiFavoritesPhotosSideBarAction(this._account);    
            HelloTipiPlugin.ShellService.RegisterSidebarAction(SidebarActionCategory.Extras, fav);
           
            //HelloTipiPlugin.ShellService.RegisterSidebarAction();
        }

        #region ISession Members

        public IAccount Account
        {
            get { return this._account; }
        }

        public ISidebarAction SidebarAction
        {
            get { return this._SidebarItem; }
        }

        public void Start()
        {
            //HelloTipiPlugin.LogInfo("Session start");
            //this.api.verify_credentials();

            this.api.my_sites();
        }

        public void Stop()
        {
            // HelloTipiPlugin.LogInfo("Session Stop");

            /*_PostingProviders.ForEach<FamilyPostingProvider>(delegate(FamilyPostingProvider provider)
            {
                HelloTipiPlugin.PostingService.UnregisterPostingProvider(provider);
            });*/
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {

        }

        #endregion

        #region ITimelineItemsProvider Members

        public event EventHandler<TimelineItemEventArgs> ItemAdded;

        public event EventHandler<TimelineItemEventArgs> ItemRemoved;

        public void OnItemProcessed(ProcessingResult result)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
